package mGraph;

import java.util.Set;

public class MTNodeMeasure {

	private MTNode node;

	public MTNodeMeasure(MTNode node){
		this.node = node;
	}
	
	/**
	 * 
	 * @param dim
	 * @return
	 */
	public double getDimensionRelevance(int dim){
		MTNodeSet neigh = node.getNeighbours();
		MTNodeSet neighSet = node.getNeighboursSet(dim);
		if(neigh!=null && neighSet!=null &&neigh.getNodes().size()>0){
			
			return (double) neighSet.getNodes().size()/neigh.getNodes().size();
		}
		else return 0.0;
	}
	
	
	/**
	 * 
	 * @param dim
	 * @return
	 */
	public double getDimensionRelevanceXor(int dim){
		MTNodeSet neigh = node.getNeighbours();
		MTNodeSet neighXor = node.getNeighboursXor(dim);
		if(neigh!=null && neighXor!=null &&neigh.getNodes().size()>0){
			
			return (double) neighXor.getNodes().size()/neigh.getNodes().size();
		}
		else return 0.0;
	}
	
	/**
	 * 
	 * @param dim
	 * @return
	 */
	public double getDimensionRelevanceWeighted(int dim){
		
		double ratio = 0;
		MTNodeSet neighbours = node.getNeighbours();
		
		if(node.getMTNodeRef().containsKey(dim)){
			for(Integer u: neighbours.getNodes()){
			
				if(node.getMTNodeRef().get(dim).containsNode(u)){
					int edge_on_dim = 1; 
					int total_edge = node.getCountEdgeBetween(u);
					double partial_ratio = (double) edge_on_dim/total_edge;
					ratio += partial_ratio;
				}
			}
		}

		if(node.getNeighbours()!=null)
			return ratio/node.getNeighbours().getNodes().size();	
		else return 0;
	}


	/**
	 * Restituisce il numero di clique triangolari aventi il nodo corrente come vertice
	 * nella dimensione passata come parametro
	 * 
	 * @param d
	 * @param g 
	 * @return
	 */
	public int getNumberTriangles(int d, MTGraph g){
		int res = 0;
		// vettore contenente i potenziali secondi vertici della clique
		MTNodeSet neighbours = node.getNeighboursSet(d);
		MTNodeSet SecondLevelNeighbours = new MTNodeSet();
		
		//Ottengo i vicini di secondo livello
		if(neighbours!=null){
			for(Integer i: neighbours.getNodes()){
				Set<Integer> temp = g.getNode(i).getNeighboursSet(d).getNodes();
				for(Integer sd: temp) SecondLevelNeighbours.addMTNode(sd, 0);
			}
		}
		
		//Controllo se si chiudono clique
		if(SecondLevelNeighbours!=null){
			for(Integer i: SecondLevelNeighbours.getNodes()){
				if(g.getNode(i).getNeighboursSet(d).containsNode(node.getId())){
					res++;
				}
			}
		}
	
		return res;
	}


	/**
	 * Restituisce il numero di clique triangolari aventi il nodo corrente come vertice
	 * in una qualsiasi delle dimensioni del grafo
	 * 
	 * @param g 
	 * @return
	 */
	public int getNumberMultidimensionalTriangles(MTGraph g){
		int res = 0;
		// vettore contenente i potenziali secondi vertici della clique
		MTNodeSet neighbours = node.getNeighbours();
		
		for(Integer i: neighbours.getNodes()){
			if(g.getNode(i).getNeighbours().containsNode(node.getId())){
				res++;
			}
		}
	
		return res;
	}
}
